package com.cskaoyan.user.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.util.Md5Utils;
import com.cskaoyan.user.constants.UserRetCode;
import com.cskaoyan.user.dal.entitys.Member;
import com.cskaoyan.user.dal.entitys.UserVerify;
import com.cskaoyan.user.dal.persistence.MemberMapper;
import com.cskaoyan.user.dal.persistence.UserVerifyMapper;
import com.cskaoyan.user.form.UserRegisterRequest;
import com.cskaoyan.user.form.UserVerifyRequest;
import com.cskaoyan.user.service.IUserRegisterService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import static com.cskaoyan.user.constants.UserRetCode.*;

/**
 * @Aurhor: 帅的一批
 * @CreateAt: 2022/10/25 21:37
 * @Description:
 * @PACKAGE_NAME： com.cskaoyan.user.service.impl
 */
@Slf4j
@Service
public class UserRegisterServiceImpl implements IUserRegisterService {

//    public static final String MAIL_SUBJECT = "用户激活认证";
//    public static final String VERIFY_URL = "http://localhost:8080/user/verify";
    //在yml中获取值
    @Value("${spring.mail.username}")
    String mailUserName;

    @Value("${email.subject}")
    String mailSubject;

    @Value("${email.text}")
    String mailUrl;

    @Autowired
    JavaMailSender mailSender;

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserVerifyMapper userVerifyMapper;

    @Override
    public void register(UserRegisterRequest request) {

        Example example = new Example(Member.class);
        example.createCriteria()
                .orEqualTo("username", request.getUserName())
                .orEqualTo("email", request.getEmail());

        Member member1 = memberMapper.selectOneByExample(example);
        if (member1 != null) {
            //用户名重复异常
            if (!StringUtils.isEmpty(member1.getUsername())) {
                throw new BizException(UserRetCode.USERNAME_ALREADY_EXISTS.getCode(), UserRetCode.USERNAME_ALREADY_EXISTS.getMessage());
            }
            //邮箱重复异常
            if (!StringUtils.isEmpty(member1.getEmail()) && member1.getEmail().equals(request.getEmail())) {
                throw new BizException(UserRetCode.EMAIL_ALREADY_EXISTS.getCode(),
                        UserRetCode.EMAIL_ALREADY_EXISTS.getMessage());
            }
        }

        Member member = new Member();
        member.setUsername(request.getUserName());
        //用户密码进行md5散列放入
        member.setPassword(Md5Utils.getMd5(request.getUserPwd()));
        member.setEmail(request.getEmail());
        member.setCreated(new Date());
        member.setUpdated(new Date());
        member.setState(0);
        member.setIsVerified("N");
        memberMapper.insert(member);

        UserVerify userVerify = new UserVerify();
        //将用用户名和用户邮箱进行拼接后进行哈希 最后得到uuid 用于用户认证
        String uuid = Md5Utils.getMd5(member.getUsername() + member.getEmail() + UUID.randomUUID().toString());
        userVerify.setUuid(uuid);
        userVerify.setIsExpire("N");
        userVerify.setIsVerify("N");
        userVerify.setRegisterDate(new Date());
        userVerify.setUsername(member.getUsername());
        int i = userVerifyMapper.insert(userVerify);
        if (i != 1) {
            throw new BizException(UserRetCode.USER_REGISTER_VERIFY_FAILED.getCode(),
                    UserRetCode.USER_REGISTER_VERIFY_FAILED.getMessage());
        }
        //开一个线程去发送邮件
        new Thread(new Runnable() {
            @Override
            public void run() {
                sendMail(uuid, request);
            }
        }).start();

    }

    /**
     * 用户注册成功以后发送邮件
     *
     * @param uuid
     * @param request
     */
    private void sendMail(String uuid, UserRegisterRequest request) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject(mailSubject);
        message.setFrom(mailUserName);
        message.setTo(request.getEmail());

//        StringBuffer stringBuffer = new StringBuffer();
//        stringBuffer = stringBuffer.append(VERIFY_URL).append("?uid=").append(uuid).append("&username=").append(request.getUserName());
        message.setText(String.format(mailUrl,request.getUserName(),uuid));
        mailSender.send(message);

        log.info("邮件发送成功");
    }


    /**
     * 焦哥 认证以后 记得将数据库中member表中的isVerify字段改为Y
     *
     * @param request
     */
    @Transactional
    @Override
    public void verify(UserVerifyRequest request) {
        Example example = new Example(UserVerify.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", request.getUsername());
        //查询userVerify表,查看用户是否存在
        List<UserVerify> members = userVerifyMapper.selectByExample(example);
        if (members == null || members.size() <= 0) {
            throw new BizException(USER_NOT_EXIST_ERRROR.getCode(), USER_NOT_EXIST_ERRROR.getMessage());
        }


        UserVerify member1 = members.get(0);
        // 判断uuid是否相同
        if(!request.getUuid().equals(member1.getUuid())){
            throw new BizException(USER_UUID_ERROR.getCode(), USER_UUID_ERROR.getMessage());
        }
        // 查看用户是否已经激活
        if ("Y".equals(member1.getIsVerify())) {
            throw new BizException(USER_ISVERIFY.getCode(), USER_ISVERIFY.getMessage());
        }
        //修改member表中verify字段
        Member member = new Member();
        member.setIsVerified("Y");
        Example memberExample = new Example(Member.class);
        Example.Criteria memberExampleCriteria = memberExample.createCriteria();
        memberExampleCriteria.andEqualTo("username", request.getUsername());
        memberMapper.updateByExampleSelective(member, memberExample);
        //修改user_verify表中的verify字段
        UserVerify userVerify = new UserVerify();
        userVerify.setIsVerify("Y");
        userVerifyMapper.updateByExampleSelective(userVerify, example);
    }
}
